"""
@Project:p8项目
@File:oauth_user.py
@Author:柴奇峰
@Date:10:33
"""
import time
import json

import hmac
import urllib
from urllib.parse import parse_qs, urlencode
import base64
import requests
from werkzeug.security import check_password_hash
from common.uilts.jwt_auth import _generate_token
from flask import Blueprint,jsonify
from flask_restful import Api,Resource,reqparse
from model import db
from model.user_model import User,OAuthUserModel

oauth_user_bp = Blueprint('oauth_user',__name__,url_prefix='/oauth')
# 创建蓝图的主入口
api = Api(oauth_user_bp)


class DingDingResource(Resource):

    def get_ding_user(self,code):
        """获取扫码登录的用户信息"""
        # 2. 构建三个参数的值

        base_url = "https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature="
        appid = "dingoajf8cqgyemqarekhr"
        appSecret = 'Fcah25vIw-koApCVN0mGonFwT2nSze14cEe6Fre8i269LqMNvrAdku4HRI2Mu9VK'
        # 把时间戳转换成毫秒
        timestamp = str(int(time.time()) * 1000)
        print('时间戳',timestamp)
        # .digest()获取hash对象的值
        signature = base64.b64encode(
            hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod='sha256').digest())
        # params 是查询字符串参数
        # data 是请求体参数
        # header 指明传递参数的类型
        # 拼接url
        url = base_url + urllib.parse.quote(signature.decode('utf-8')) + "&timestamp=" + timestamp + "&accessKey=" + appid
        print("url>>>>", url)
        resp = requests.post(url, data=json.dumps({'tmp_auth_code': code}),
                             headers={'Content-Type': 'application/json'})
        return resp.json()

    def get(self):
        """
        1.获取code值
        2. 构建accessq 3Key(应用的AppKey)
         timestamp，(当前的时间戳，是单位毫秒)
         signature:(appSecret计算出来的签名值)
         三个参数的值
        3. 发起请求：
        post https://oapi.dingtalk.com/sns/getuserinfo_bycode?accessKey=ACCESS_KEY&timestamp=TIMESTAMP&signature=SIGNATURE
        :return: userInfo
        """
        parser = reqparse.RequestParser()
        parser.add_argument('code')
        args = parser.parse_args()
        # 1.获取code值
        code = args.get('code')
        print('code',code)
        # 根据code获取钉钉用户信息
        ding_user = self.get_ding_user(code)
        print('用户信息',ding_user)
        if ding_user['errcode'] != 0:
            return jsonify(msg="获取钉钉用户信息失败", code=500)
        # 获取钉钉的openid
        openid = ding_user['user_info']['openid']
        if openid:
            # 根据openid 判定是否绑定账号
            oauth_user = OAuthUserModel.query.filter_by(uid=openid).first()
            if oauth_user:
                # 查询到用户,已经绑定过,
                user = User.query.filter_by(uid=oauth_user.user).first()
                # 返回绑定成功的用户token 及id
                token, refresh_token = _generate_token({'account': user.account, 'user_id': user.uid,
                                                        'is_superuser': user.is_superuser})
                print('登陆的token', token)

                return jsonify(msg="登陆成功", data={'code': 200, 'token': token, 'refresh': refresh_token,
                                                 'account': user.account, 'uid': user.uid})
            else:
                return jsonify(msg="没有绑定用户,请先绑定", data={'uid': openid})

class DingBindUser(Resource):
    def post(self):
        """绑定账号"""
        parser = reqparse.RequestParser()
        parser.add_argument('account')
        parser.add_argument('password')
        parser.add_argument('unid')
        args = parser.parse_args()
        uname = args.get('account')
        pwd = args.get('password')
        openid = args.get('unid')
        # 判断账号是否注册过,没有注册过去注册
        print("?????", uname, pwd, openid)

        user = User.query.filter_by(account=uname).first()
        if not user:
            return jsonify(msg="请先注册网站", code=400)
        # 校验密码

        rest = user.password == pwd
        if not rest:
            return jsonify(msg="密码错误", code=400)
        # 根据user 查询oauthuser表中的数据, 绑定第三方账号
        oauth = OAuthUserModel(image='', oauth_id=openid, user=user.uid, oauth_type='qq')
        db.session.add(oauth)
        db.session.commit()
        # 返回绑定成功的用户token 及id
        token, refresh_token = _generate_token({'account': user.account, 'user_id': user.uid,
                                                })
        print('登陆的token', token)
        return jsonify(msg="绑定成功", code=200, data={'token': token, 'refresh': refresh_token,
                                                   'account': user.account, 'uid': user.uid})




class OauthWeiboLogin(Resource):
    def get_weibo_user(self, code):
        data_ = {
            "client_id": "2775107052",
            "client_secret": "718b38b04fc387700cc1595b30875b19",
            "grant_type": "authorization_code",
            "redirect_uri": "http://127.0.0.1:8080/weibo",
            "code": code,
        }
        base_url = "https://api.weibo.com/oauth2/access_token"
        try:
            resp = requests.post(url=base_url, data=data_).json()
            print("=======>resp", resp)
        except Exception as e:
            return {"message": "获取微博用户信息失败", "code": 400}

        if not resp["access_token"]:
            return {"message": "根据code获取钉钉用户信息失败", "code": 400}
        else:
            user_dict = resp
            return user_dict

    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument("code")
        args = parser.parse_args()
        code = args["code"]
        print("------->微博的code", code)

        user_dict = self.get_weibo_user(code)
        print("======>user_dict", user_dict)
        access_token = user_dict["access_token"]
        print("------>access_token", access_token)
        oauth_user = OAuthUserModel.query.filter_by(uid=access_token, oauth_type="weibo").first()
        print("------>oauth_user", oauth_user)
        if oauth_user:
            user = User.query.filter_by(uid=oauth_user.user).first()
            # payload = {"uid": user.uid}
            # token = _generate_token(payload)
            data_ = {
                "account": user.account,
                "id": user.uid,
                # "token": token
            }
            return {"message": "登录成功", "code": 200, "data": data_}
        else:
            return {"message": "用户没有绑定，请先绑定", "code": 500, "uid": access_token}

class WeiboBindUser(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument("account")
        parser.add_argument("password")
        parser.add_argument("unid")
        args = parser.parse_args()
        account = args["account"]
        password = args["password"]
        unid = args["unid"]
        print("------->unid", unid)
        user = User.query.filter_by(account=account).first()
        if not user:
            return {"message": "用户未注册，请先注册", "code": 400}

        else:
            if not check_password_hash(user.password, password):
                return {"message": "密码错误", "code": 400}
            else:
                oauth_user = OAuthUserModel(uid=unid, user=user.uid, oauth_type="weibo")
                db.session.add(oauth_user)
                db.session.commit()
                # payload = {"uid": user.uid}
                # token = _generate_token(payload)
                data_ = {
                    "uid": user.uid,
                    "account": user.account,
                    # "token": token,
                }
                return {"message": "绑定成功", "code": 200, "data": data_}


api.add_resource(DingDingResource,'/dingding')
api.add_resource(DingBindUser,'/dingding/bind')
api.add_resource(WeiboBindUser,'/weibo')